package maple.util.tasks;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Vector;

import maple.lang.Command;
import maple.lang.Language;
import maple.util.Task;

public class ApplicationTask extends Task
{
	public static enum Property{ LOCATION };

	private String _master;
	private Vector< String > _locations;
	private HashMap< String, Boolean > _plans;
	private int _state;

	/**
	 * construct a new task with the specified sender, command, receiver and master
	 *
	 * @param	sender		the specified sender
	 * @param	command		the specified command
	 * @param	receiver	the specified receiver
	 * @param	master		the specified master
	 *
	 * @author	snowfoxy
	 * @since	2011-11-26
	 */
	public ApplicationTask( final String sender, final Command command, final String receiver, final String master )
	{
		super( sender, command, receiver );

		if( _available )
		{
			_master = master;
			_locations = new Vector< String >( Arrays.asList( command.getParameter( ApplicationTask.Property.LOCATION.toString() ).split( Language.COMMA ) ) );
			_plans = new HashMap< String, Boolean >();
			_state = 0;
		}
	}

	/**
	 * return the locations of this task or null if this task is not available
	 *
	 * @return	the locations of this task
	 *
	 * @author	snowfoxy
	 * @since	2011-11-26
	 */
	public Vector< String > getLocations()
	{
		if( _available )
		{
			return _locations;
		}
		return null;
	}

	/**
	 * return the master of this task or null if this task is not available
	 *
	 * @return	the master of this task 
	 *
	 * @author	snowfoxy
	 * @since	2011-11-26
	 */
	public String getMaster()
	{
		if( _available )
		{
			return _master;
		}
		return null;
	}

	/**
	 * return true if this task is dispatched or false if this task is not available
	 *
	 * @return	true if this task is dispatched
	 *
	 * @author	snowfoxy
	 * @since	2011-11-26
	 */
	public boolean isDispatched()
	{
		if( _available )
		{
			for( Boolean plan : _plans.values() )
			{
				if( !plan )
				{
					return false;
				}
			}
			return true;
		}
		return false;
	}
	/**
	 * return true if this task is finished or false if this task is not available
	 *
	 * @return	true if this task is finished
	 *
	 * @author	snowfoxy
	 * @since	2011-11-26
	 */
	public boolean isFinished()
	{
		if( _available )
		{
			if( _state == _plans.size() )
			{
				return true;
			}
		}
		return false;
	}

	/**
	 * return true if this task is valid 
	 *
	 * @return	true if this task is valid 
	 *
	 * @author	snowfoxy
	 * @since	2011-11-25
	 */
	protected boolean isValid()
	{
		if( super.isValid() && _instruction == Language.Instruction.SUBSCRIBE )
		{
			return true;
		}
		return false;
	}

	/**
	 * return the plans with the specified interval or null if this task is not available
	 *
	 * @param	interval	the specified interval
	 * @return	the plans with the specified interval
	 *
	 * @author	snowfoxy
	 * @since	2011-11-26
	 */
	public Vector< String > setInterval( final String interval )
	{
		if( _available )
		{
			Vector< String > commands = new Vector< String >();
			for( String plan : _plans.keySet() )
			{
				Command command = new Command( plan );
				command.setParameter( MasterTask.Property.INTERVAL.toString(), interval );
				commands.add( command.toString() );
			}
			return commands;
		}
		return null;
	}

	/**
	 * set the specified status of the specified plan
	 *
	 * @param	plan	the specified plan 
	 * @param	value	the status of the specified plan
	 *
	 * @author	snowfoxy
	 * @since	2011-11-26
	 */
	public void setPlan( final String plan, final boolean value )
	{
		if( _available )
		{
			++_state;
			_plans.put( plan, value );
		}
	}

	/**
	 * set the plans of this task 
	 *
	 * @param	plans	the specified plans
	 *
	 * @author	snowfoxy
	 * @since	2011-11-26
	 */
	public void setPlans( final Vector< String > plans )
	{
		if( _available )
		{
			for( String plan : plans )
			{
				_plans.put( plan, false );
			}
		}
	}
}
